#include "configdata.h"
#include <fstream>

ConfigData *ConfigData::m_configData = NULL;

ConfigData *ConfigData::GetInstance()
{
	if(m_configData == NULL){
		m_configData = new ConfigData();
	}
	return m_configData;
}

ConfigData::ConfigData()
{
    this->Initialize();
}

ConfigData::~ConfigData()
{
	delete[] m_tranList;
	delete[] m_genList;
}

void ConfigData::Initialize()
{
    m_tranList = new TTranSetting[N_TRANSACTIONS];
	for(int i = 0; i < N_TRANSACTIONS; i ++){
		m_tranList[i].isOn = false;
		m_tranList[i].ratio = 0;
	}
    m_duration = 0;
    m_incUser = 0;
    m_incTime = 0;
    m_genList = new TGenConfig[MaxGenCount];

	for(int i = 0; i < MaxGenCount; i ++){
		m_genList[i].ip = "";
		m_genList[i].isOn = false;
		m_genList[i].userCount = -1;
	}
	m_updateRate = 1;
	m_serverIP = "localhost";
}

void ConfigData::registerObserver(ConfigObserver *observer)
{
	m_observers.push_back(observer);
}

void ConfigData::removeObserver(ConfigObserver *observer)
{
	m_observers.remove(observer);
}

void ConfigData::notifyObservers()
{
    for(std::list<ConfigObserver *>::iterator it = m_observers.begin(); it != m_observers.end(); ++ it){
        ((ConfigObserver *)(*it))->update();
    }
}

int ConfigData::addGen(std::string ip, int userCount)
{
    // find an availabel index
    int i;
    for(i = 0; i < MaxGenCount; i ++){
        if(m_genList[i].userCount == -1) break; // userCount = -1 marks it as available
    }

    if(i < MaxGenCount){
        m_genList[i].ip = ip;
        m_genList[i].userCount = userCount;
        return i;
    }
    return -1;
}

void ConfigData::delGen(int genId)
{
    if(genId < MaxGenCount){
        m_genList[genId].ip = "";
        m_genList[genId].isOn = false;
        m_genList[genId].userCount = -1;
    }
}

void ConfigData::setGenConfig(int genId, const TGenConfig &config)
{
    m_genList[genId] = config;
}

void ConfigData::setTranSetting(int tranType, const TTranSetting &setting)
{
    m_tranList[tranType] = setting;
}

TGenConfig ConfigData::getGenConfig(int genId)
{
    return m_genList[genId];
}

TTranSetting ConfigData::getTranSetting(int tranType)
{
	return m_tranList[tranType];
}

int ConfigData::getDuration()
{
	return m_duration;
}

void ConfigData::setDuration(int duration)
{
	m_duration = duration;
}

int ConfigData::getIncUser()
{
	return m_incUser;
}

void ConfigData::setIncUser(int user)
{
	m_incUser = user;
}

int ConfigData::getIncTime()
{
	return m_incTime;
}

void ConfigData::setIncTime(int sec)
{
	m_incTime = sec;
}

int ConfigData::getUpdateRate()
{
	return m_updateRate;
}

void ConfigData::setUpdateRate(int rate)
{
	// the actual time is m_updateRate * 5 sec
	int tmp = rate / 5 + 1;
	if(rate % 5 == 0) --tmp;
	m_updateRate = tmp;
}

void ConfigData::setServerIP(std::string ip)
{
	m_serverIP = ip;
}

std::string ConfigData::getServerIP()
{
	return m_serverIP;
}

void ConfigData::loadConfig(std::string fileName)
{
	std::ifstream file;
	file.open(fileName.c_str());

	if(!file.is_open()){
		qDebug() << "cannot open file: " << fileName.c_str();
		return;
	}

	//load tran setting
	for(int i = 0; i < N_TRANSACTIONS; i ++){
		file >> m_tranList[i].isOn >> m_tranList[i].ratio;
	}

	// load duration, incuser, inctime
	file >> m_duration;
	file >> m_incUser >> m_incTime;

	// load update rate, server IP
	file >> m_updateRate; 
	file >> m_serverIP; 

	// load gen list
	for(int i = 0; i < MaxGenCount; i ++){
		file >> m_genList[i].ip >> m_genList[i].isOn >> m_genList[i].userCount;
	}

	file.close();
	notifyObservers();
}

void ConfigData::dumpConfig(std::string fileName)
{
	std::ofstream file;
	file.open(fileName.c_str());
	if(!file.is_open()){
		qDebug() << "cannot open file: " << fileName.c_str();
		return;
	}

	//dump tran setting
	for(int i = 0; i < N_TRANSACTIONS; i ++){
		file << m_tranList[i].isOn << " " << m_tranList[i].ratio << std::endl;
	}

	// dump duration, incuser, inctime
	file << m_duration << std::endl;
	file << m_incUser << " " << m_incTime << std::endl;

	// dump update rate, server IP
	file << m_updateRate << std::endl;
	file << m_serverIP << std::endl;

	// dump gen list
	for(int i = 0; i < MaxGenCount; i ++){
		file << m_genList[i].ip << " " << m_genList[i].isOn << " " << m_genList[i].userCount << std::endl;
	}

	file.close();
}
